package org.apache.ibatis.common.type;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * @Name TypeReference
 * @Description: 类型引用 [工具]
 * 描述信息：该类主要用于解析当前 TypeHandler 类型处理器能够处理的 Java 类型。
 * @Version v1.0.0
 * @Author: lichao
 * @Date: 2024-05-09 17:06:45
 **/
public abstract class TypeReference<T> {
    private final Type rawType;

    protected TypeReference() {
        rawType = getSuperclassTypeParameter(getClass());
    }

    /**
     * 解析当前 TypeHandler 类型处理器能够处理的 Java 类型
     *
     * @param clazz 类型处理器
     * @return java.lang.reflect.Type 结果
     * @version v1.0.0
     * @author lichao
     * @date 2024-05-09 17:11:24
     */
    Type getSuperclassTypeParameter(Class<?> clazz) {
        // 获取 clazz 类中所有带泛型的直接父类 genericSuperclass
        Type genericSuperclass = clazz.getGenericSuperclass();
        // 判断 genericSuperclass 是否为 Class 类型
        if (genericSuperclass instanceof Class) {
            // 如果 genericSuperclass 不是 TypeReference 类型本身
            if (genericSuperclass != TypeReference.class) {
                // 说明没有解析到足够上层，递归调用
                return getSuperclassTypeParameter(clazz.getSuperclass());
            }
            // 说明 clazz 是 TypeReference 类型的子类，但是却没有使用泛型，抛出异常。
            String errorMsg = "类型处理器 [" + getClass() + "] 是 TypeReference 的子类，但是却丢失了类型参数：删除该类型处理器，或者为其添加一个类型参数。";
            throw new TypeException(errorMsg);
        }
        // 说明 genericSuperclass 是泛型类型，获取泛型的第一个参数 T
        Type rawType = ((ParameterizedType) genericSuperclass).getActualTypeArguments()[0];
        // 如果 T 是参数化类型
        if (rawType instanceof ParameterizedType) {
            // 获取参数化类型的实际类型
            rawType = ((ParameterizedType) rawType).getRawType();
        }
        return rawType;
    }

    public final Type getRawType() {
        return rawType;
    }

    @Override
    public String toString() {
        return "TypeReference{" +
                "rawType=" + rawType +
                '}';
    }
}

